/*
 * RenzoSceneNode.h
 *
 *  Created on: Aug 30, 2009
 *      Author: sonhua
 */

#ifndef RENZOSCENENODE_H_
#define RENZOSCENENODE_H_

#include "RenzoMustHave.h"
#include "RenzoPrecompiled.h"

#include <map>
using namespace std;

//#include <hash_map>
//using namespace stdext;

#include "RenzoBoundingBox.h"
#include "RenzoIteratorWrappers.h"

namespace Renzo {
	class RENZODERER_API SceneNode {
	public:
		SceneNode();
		virtual ~SceneNode();

	protected:
		Float3 translation;
		Float3 rotation;
		Float3 scale;
		Matrix4 matTransform;

	///
	/// attached objects
	///
	public:
		void attachObject(Object* obj);
		void attachObject(const String& name, Object* obj);
		void detachObject(Object* obj);
		void detachObject(const String& name);
		
		Object* getAttachedObject(const String& name);				
	protected:		
		//typedef stdext::hash_map<String, Object*> ObjectList;
		typedef map<ResourceID, Object*> ObjectList;
		ObjectList objects;

	///
	/// Attached object iterator
	///	
	public:
		typedef MapIterator<ObjectList> ObjectIterator;		
		MapIterator<ObjectList> getObjectIterator();
	
	///
	/// scene hierarchy
	///
	public:
		SceneNode* parent;

		// Here we need parent to point to child scene nodes of the upper level.
		// And to be safe, do not store SceneNode directly in std::vector.
		// Instead, use SceneNode* (pointer). 
		// The reason is to avoid dangling pointer cases 
		// as the content of the vector may be relocated when the vector is expanding its capacity.
		typedef std::vector<SceneNode*> SceneNodeList; 
		SceneNodeList childNodes;

	public:
		virtual void copyToHardware();

	public:
		void setRotation(const Float3& rot);
		Float3 getRotation() const;
		void setTranslation(const Float3& trans);
		Float3 getTranslation() const;
		void setScale(const Float3& scale);
		Float3 getScale() const; 

	public:
		virtual void update(int delta);
		BoundingBox* getBoundingBoxAABB();
	protected:
		BoundingBox bb;
	};

}

#endif /* RENZOSCENENODE_H_ */
